﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using TcpLib;

namespace TcpServer
{
    public class SocketPolicyServiceProvider : TcpServiceProvider
    {
        const string _PolicyRequestString = "<policy-file-request/>";
        private byte[] _Policy = null;
        private string policyFilePath;

        public SocketPolicyServiceProvider( string policyFilePath )
        {
            this.policyFilePath = policyFilePath;
            using ( FileStream fs = new FileStream( policyFilePath, FileMode.Open ) )
            {
                _Policy = new byte[fs.Length];
                fs.Read( _Policy, 0, _Policy.Length );
            }
        }

        public override object Clone()
        {
            return new SocketPolicyServiceProvider( this.policyFilePath );
        }

        public override void OnReceiveData( TcpLib.ConnectionState state )
        {
            byte[] buffer = new byte[1024];
            int totalReadBytes = 0;
            string request = string.Empty;
            MemoryStream ms = new MemoryStream();

            while ( state.AvailableData > 0 )
            {
                int readBytes = state.Read( buffer, 0, state.AvailableData > 1024 ? 1024 : state.AvailableData );
                if ( readBytes > 0 )
                    ms.Write( buffer, 0, readBytes );
                totalReadBytes += readBytes;
            }

            if ( totalReadBytes > 0 )
            {

                request = Encoding.UTF8.GetString( ms.ToArray() ).Trim();
                if ( StringComparer.InvariantCultureIgnoreCase.Compare( request, _PolicyRequestString ) != 0 )
                {
                    //Data received isn't valid so close
                    state.EndConnection();
                    return;
                }
                state.Write( this._Policy, 0, this._Policy.Length );
                state.EndConnection();
                System.Diagnostics.Debug.WriteLine( request );

            }
            else state.EndConnection(); //If read fails then close connection
        }

        public override void OnDropConnection( TcpLib.ConnectionState state )
        {
            // do nothing
        }

        public override void OnAcceptConnection( TcpLib.ConnectionState state )
        {
            // do nothing
        }
    }
}
